package javase.collections;

import java.util.ArrayList;
import java.util.List;

public class ArrayListPOC {
	private final static int INITIAL_LIST_CAPACITY = 10;
	private final static int NEW_ELEMENTS_AMOUNT = 10;

	private static volatile int newElementsMinValue = 100;

	private static List<Integer> list;

	public static void main(String[] args) {
		list = getInitializedArrayList();
		System.out.println("Created initial list " + list);
		Thread printer = new Thread(new ListPrinter(list), "printer");
		Thread modifier = new Thread(new ListModifier(list), "modifier");
		System.out.println("Starting threads");
		printer.start();
		modifier.start();
		System.out.println("main " + list);
		System.out.println("End of main");
	}

	private static ArrayList<Integer> getInitializedArrayList() {
		ArrayList<Integer> result = new ArrayList<Integer>();
		for (int i = 0; i < INITIAL_LIST_CAPACITY; i++) {
			result.add(i);
		}
		return result;
	}

	private static class ListModifier implements Runnable {
		private List<Integer> list;

		public ListModifier(List<Integer> list) {
			this.list = list;
		}

		@Override
		public void run() {
			System.out.println("ListModifier runs");
			while (true) {
				synchronized (list) {
					for (int i = 0; i < NEW_ELEMENTS_AMOUNT; i++) {
						list.add(newElementsMinValue++);
					}
				}
				System.out.println("ListModifier: " + list);
			}
		}
	}

	private static class ListPrinter implements Runnable {
		private List<Integer> list;

		public ListPrinter(List<Integer> list) {
			this.list = list;
		}

		@Override
		public void run() {
			System.out.println("ListPrinter runs");
			while (true) {
				synchronized (list) {
					for (Integer current : list) {
						System.out.println("ListPrinter: " + current);
					}
				}
				System.out.println("Cycle End");
			}
		}

	}
}
